﻿#include "DateTimeTimer.h"
#include <limits.h>
#include <QDebug>

DateTimeTimer::DateTimeTimer(QObject *parent) : QObject(parent)
{
    m_interval = E_DAY;
    connect(&m_timer, &QTimer::timeout, this, &DateTimeTimer::onTimeout);
}

int DateTimeTimer::msecsTo(const QTime &t)
{
    QTime now = QTime::currentTime();
    int msecs = now.msecsTo(t);
    //qDebug() << "old old msecs = " << msecs;
    if(msecs <= 0)  msecs += (3600 * 24 * 1000);
    return msecs;
}

qint64 DateTimeTimer::msecsTo(const QDateTime &dt)
{
    QDateTime now = QDateTime::currentDateTime();
    qint64 msecs = now.msecsTo(dt);
    return msecs;
}

bool DateTimeTimer::start(const QTime &t)
{
    if(!t.isValid()) return false;
    int msecs = msecsTo(t);
    m_timer.start(msecs);
    return true;
}

bool DateTimeTimer::start(const QDateTime &dt)
{
    if(!dt.isValid()) return false;
    qint64 msecs = msecsTo(dt);
    if(msecs < 0 || msecs > INT_MAX) return false;
    m_timer.start(static_cast<int>(msecs));
    return true;
}
const int MINUTE_MSECS = 60 * 1000;
const int HOUR_MSECS = 3600 * 1000;
const int HALF_DAY_MSECS = 12 * HOUR_MSECS;
void DateTimeTimer::onTimeout()
{
    int msecs;
    if(!m_timer.isSingleShot())
    {
        msecs = msecsTo(m_time);
        //qDebug() << "old msecs = " << msecs;
        switch (m_interval)
        {
        case E_HALFDAY:
            msecs = msecs % HALF_DAY_MSECS;
            if(msecs == 0)  msecs = HALF_DAY_MSECS;
            break;
        case E_HOUR:
            msecs = msecs % HOUR_MSECS;
            if(msecs == 0)  msecs = HOUR_MSECS;
            break;
        case E_MINUTE:
            msecs = msecs % MINUTE_MSECS;
            if(msecs == 0)  msecs = MINUTE_MSECS;
            break;
        default:
            break;
        }
        //qDebug() << "new msecs = " << msecs;
        m_timer.start(msecs);
    }
    emit timeout();
}

bool DateTimeTimer::singleShot(const QDateTime &dt, const QObject *receiver, const char *member)
{
    if(!dt.isValid()) return false;
    qint64 msecs = msecsTo(dt);
    if(msecs < 0 || msecs > INT_MAX) return false;
    QTimer::singleShot(static_cast<int>(msecs), receiver, member);
    return true;
}

bool DateTimeTimer::singleShot(const QDateTime &dt, Qt::TimerType timerType, const QObject *receiver, const char *member)
{
    if(!dt.isValid()) return false;
    qint64 msecs = msecsTo(dt);
    if(msecs < 0 || msecs > INT_MAX) return false;
    QTimer::singleShot(static_cast<int>(msecs), timerType, receiver, member);
    return true;
}

bool DateTimeTimer::singleShot(const QTime &t, const QObject *receiver, const char *member)
{
    if(!t.isValid()) return false;
    int msecs = msecsTo(t);
    QTimer::singleShot(msecs, receiver, member);
    return true;
}

bool DateTimeTimer::singleShot(const QTime &t, Qt::TimerType timerType, const QObject *receiver, const char *member)
{
    if(!t.isValid()) return false;
    int msecs = msecsTo(t);
    QTimer::singleShot(msecs, timerType, receiver, member);
    return true;
}
